cmake_minimum_required(VERSION 3.20)
project(sparrowstl VERSION 0.0.3 LANGUAGES C CXX)

if(NOT CMAKE_CXX_STANDARD)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)
endif(NOT CMAKE_CXX_STANDARD)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif(NOT CMAKE_BUILD_TYPE)

if(NOT USE_DEBUG)
    set(USE_DEBUG)
endif(NOT USE_DEBUG)

# 没有明确指出动态库或静态库时，默认
option(BUILD_SHARED_LIBS "on lib default share lib, off default static lib" OFF)

# 设置googletest
set(GOOGLE_TEST_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/third_lib/gtest/include")
set(GOOGLE_TEST_LIB_DIR "${CMAKE_SOURCE_DIR}/third_lib/gtest/lib")
include_directories(${GOOGLE_TEST_INCLUDE_DIR})
link_directories(${GOOGLE_TEST_LIB_DIR})

# 动态库位置
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# 可执行程序位置
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 静态库位置
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/arc)

# 设置CXX_flags
set(CMAKE_CXX_FLAGS 
    "-fno-rtti \
    -Wall \
    -Wextra \
    -Werror \
    -Wold-style-cast\
    -Wshadow \
    -march=native \
    -Wwrite-strings \
    -Wconversion \
    -g "
    )

# 添加线程库
find_package(Threads)

add_subdirectory(exception)
add_subdirectory(iterator)
add_subdirectory(memory)
add_subdirectory(math)
add_subdirectory(utility)
add_subdirectory(container)
add_subdirectory(string)

add_library(spwstl)
set(
    all_lib_obj
    except_lib_obj
    mem_lib_obj
    complex_lib_obj
    utility_lib_obj
    con_lib_obj
    iter_lib_obj
    str_lib_obj
)
target_link_libraries(spwstl PUBLIC ${all_lib_obj})
#add_subdirectory(testsuite)

set(test_dir ${CMAKE_SOURCE_DIR}/testsuite)
set(test_libs gtest gtest_main Threads::Threads spwstl)

# test

# container
add_executable(gtest_vector ${test_dir}/gtest_vector.cc)
target_link_libraries(gtest_vector PRIVATE ${test_libs})

add_executable(gtest_array ${test_dir}/gtest_array.cc)
target_link_libraries(gtest_array PRIVATE ${test_libs})

add_executable(gtest_list ${test_dir}/gtest_list.cc)
target_link_libraries(gtest_list PRIVATE ${test_libs})

add_executable(gtest_deque ${test_dir}/gtest_deque.cc)
target_link_libraries(gtest_deque PRIVATE ${test_libs})

# except
add_executable(gtest_exception ${test_dir}/gtest_exception.cc)
target_link_libraries(gtest_exception PRIVATE ${test_libs})
# config
add_executable(gtest_config ${test_dir}/gtest_config.cc)
target_link_libraries(gtest_config PRIVATE ${test_libs})
# iterator
add_executable(gtest_iterator ${test_dir}/gtest_iterator.cc)
target_link_libraries(gtest_iterator PRIVATE ${test_libs})
# memory
add_executable(gtest_mem_cons ${test_dir}/gtest_mem_cons.cc)
target_link_libraries(gtest_mem_cons PRIVATE ${test_libs})

add_executable(gtest_mem_alloc ${test_dir}/gtest_mem_alloc.cc)
target_link_libraries(gtest_mem_alloc PRIVATE ${test_libs})

add_executable(gtest_mem_new ${test_dir}/gtest_mem_new.cc)
target_link_libraries(gtest_mem_new PRIVATE ${test_libs})

add_executable(gtest_sha_ptr ${test_dir}/gtest_sha_ptr.cc)
target_link_libraries(gtest_sha_ptr PRIVATE ${test_libs})
target_compile_options(gtest_sha_ptr PRIVATE -frtti)

add_executable(gtest_uni_ptr ${test_dir}/gtest_uni_ptr.cc)
target_link_libraries(gtest_uni_ptr PRIVATE ${test_libs})

add_executable(gtest_uninit ${test_dir}/gtest_uninit.cc)
target_link_libraries(gtest_uninit PRIVATE ${test_libs})

#math
add_executable(gtest_complex ${test_dir}/gtest_complex.cc)
target_link_libraries(gtest_complex PRIVATE ${test_libs})

# utility
add_executable(gtest_uti_move ${test_dir}/gtest_uti_move.cc)
target_link_libraries(gtest_uti_move PRIVATE ${test_libs})

add_executable(gtest_uti_pair ${test_dir}/gtest_uti_pair.cc)
target_link_libraries(gtest_uti_pair PRIVATE ${test_libs})
target_compile_options(gtest_uti_pair PRIVATE -Wno-conversion)

add_executable(gtest_uti_tuple ${test_dir}/gtest_uti_tuple.cc)
target_link_libraries(gtest_uti_tuple PRIVATE ${test_libs})

#string
add_executable(gtest_str ${test_dir}/gtest_str.cc)
target_link_libraries(gtest_str PRIVATE ${test_libs})

#algo
#add_executable(gtest_algobase ${test_dir}/gtest_algobase.cc)
#target_link_libraries(gtest_algobase PRIVATE ${test_libs})


enable_testing()
add_test(
    NAME gtest_vector
    COMMAND $<TARGET_FILE:gtest_vector>)
add_test(
    NAME gtest_array
    COMMAND $<TARGET_FILE:gtest_array>)
add_test(
    NAME gtest_exception
    COMMAND $<TARGET_FILE:gtest_exception>)
add_test(
    NAME gtest_config
    COMMAND $<TARGET_FILE:gtest_config>)
add_test(
    NAME gtest_iterator
    COMMAND $<TARGET_FILE:gtest_iterator>)
add_test(
    NAME gtest_mem_cons
    COMMAND $<TARGET_FILE:gtest_mem_cons>)
add_test(
    NAME gtest_mem_alloc
    COMMAND $<TARGET_FILE:gtest_mem_alloc>)
add_test(
    NAME gtest_mem_new
    COMMAND $<TARGET_FILE:gtest_mem_new>)
add_test(
    NAME gtest_sha_ptr
    COMMAND $<TARGET_FILE:gtest_sha_ptr>)
add_test(
    NAME gtest_uni_ptr
    COMMAND $<TARGET_FILE:gtest_uni_ptr>)
add_test(
    NAME gtest_uninit
    COMMAND $<TARGET_FILE:gtest_uninit>)
add_test(
    NAME gtest_complex
    COMMAND $<TARGET_FILE:gtest_complex>)
add_test(
    NAME gtest_uti_pair
    COMMAND $<TARGET_FILE:gtest_uti_pair>)
add_test(
    NAME gtest_uti_tuple
    COMMAND $<TARGET_FILE:gtest_uti_tuple>)
add_test(
    NAME gtest_uti_move
    COMMAND $<TARGET_FILE:gtest_uti_move>)
add_test(
    NAME gtest_str
    COMMAND $<TARGET_FILE:gtest_str>)
add_test(
    NAME gtest_list
    COMMAND $<TARGET_FILE:gtest_list>)
# add_test(
    # NAME gtest_deque
    # COMMAND $<TARGET_FILE:gtest_deque>)
#add_test(
    #NAME gtest_algobase
    #COMMAND $<TARGET_FILE:gtest_algobase>)
